perm filename LTCONS[LSP,SYS] blob
sn#059877 filedate 1974-01-15 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 TITLE LTCONS
C00003 00003 (LTSET1 <size> <bporg> <bpend> <flag>)
C00006 00004 (LTREL1 BPORG BPEND)
C00007 00005 (LTCONS <already consed list>) -- (LTXCONS A B)
C00011 00006 (UNLTCONS <ltcons'ed list>)
C00013 00007 (LTOCCUPANCY) (LTAVERAGELOOKUP)(LTMAXLOOKUP)
C00016 ENDMK
C⊗;
TITLE LTCONS
; LINEAR QUOTIENT HASHED CONS -- NOT QUITE AS GOOD AS QUAD. QUOTIENT, BUT
; EACH PROBE IS QUICKER, SO RESULT IS BETTER USUALLY.
INTERNAL LTCONS,LTXCONS,LTSET1,LTREL1,UNLTCONS
EXTERNAL CONS,XCONS,NUMVAL,FIX1A,JOBREL
P←←14
A←←1
B←←2
C←←3
D←←4
ORIGPT←←5 ;ORIGINAL HASHED ADDR FOR DONE TEST
CONSED←←6 ;LT CONSED WORD, AFTER LTCONSING CAR/CDR
HASLEN←←7 ;LENGTH OF HASH TABLE
INUM0←←577777
; (LTSET1 <size> <bporg> <bpend> <flag>)
; Allocate data for hash conses, flag is T for BPS, NIL for topcor.
LTSET1: SKIPE .HASLEN ;If there already is a hash space, (RETURN NIL)
JRST FALSE
SETZM NIL.NIL ;SPECIAL WORD FOR (NIL)
MOVEM 2,BPRSV1 ;Save original (Lisp-form) numbers
MOVEM 3,BPNDSV
MOVEM 4,FLAGSV
PUSHJ P,NUMVAL ;Fetch values:
PUSH P,1 ; 1: size
MOVEM 1,.HASLEN
MOVE 1,BPRSV1 ; 2: current bporg
PUSHJ P,NUMVAL ; 3: current bpend
PUSH P,1 ; 4: flag (unchd.) T means BPS, NIL topcore
MOVE 1,BPNDSV
PUSHJ P,NUMVAL
MOVE 3,1
POP P,2
POP P,1
SKIPE FLAGSV ;Which?
JRST LDBPS ; NIL -- BPS
MOVE 2,JOBREL
ADDI 2,1 ;Get enough core to hold the space
MOVE 3,1 ; implied by the size in 1
ADDI 3,-1(2)
CORE 3,
JRST FALSE ;Failed to set up hash space
MOVE 3,JOBREL ;New top size
LDBPS: MOVEM 2,.HASBAS ;Store base addr, make sure there's
MOVE 4,3 ; enough room, store end address
SUBI 4,-1(2) ; (real available size must be
CAMGE 4,1 ; ≥ needed one)
JRST FALSE
MOVE 3,2
ADD 3,1
MOVEM 3,.HASEND
SETZM .FULL ;Prepare for LTCONS
SETZM (2) ;Clear new array
HRLI 2,1(2)
MOVSS 2
BLT 2,-1(3)
TRUTH: MOVE 1,3 ;Return new BPORG loc, LTSET will store in
PUSHJ P,FIX1A ; BPORG, return T
MOVEM 1,BPRGSV
POPJ P,
FALSE: MOVEI 1, ;(RETURN NIL)
POPJ P,
; (LTREL1 BPORG BPEND)
LTREL1: SKIPN .HASLEN ;Don't release what you don't have
JRST FALSE
SETZM .HASLEN ;Don't have any more
SKIPN FLAGSV ;IF IN BPS, ONE TECHNIQUE, ELSE ANOTHER
JRST CORREL
CAMN 2,BPNDSV ;FORGET IF BPENDS NOT SAME
CAME 1,BPRGSV ;OR IF BPORG HAS MOVED SINCE LTSET
JRST FALSE ;DON'T CHANGE BPORG BACK
MOVE 1,BPRSV1 ;ORIGINAL BPORG
POPJ P, ;NEW BPORG, CONSIDER IT RELEASED
CORREL: SOS 1,.HASBAS
CORE 1,
JRST FALSE ;I DON'T UNDERSTAND IT
JRST FALSE
; (LTCONS <already consed list>) -- (LTXCONS A B)
LTXCONS:PUSHJ P,XCONS ;EXCHANGED CONS
LTCONS: MOVE HASLEN,.HASLEN ;HASH TABLE/CONS TABLE LEGTH
MOVE D,HASLEN ;INDICATES ONE PROBE ONLY
;D IS HASLEN IF INITIAL HASH SUCCEEDS
; -1(HASLEN) IF FIRST OFLOW SUCCEEDS
; ETC.
SETZM .FULL ;ON IF TABLE FULL (W/O THIS CONS)
LCONS1: HRRZS A ;CLEAR LH GARBAGE
JUMPE A,CPOPJ ;((NULL L) NIL)
SKIPE .FULL ;IF FULL ALREADY, RETURN INPUT
POPJ P,
CAML A,.HASBAS ;((ALREADYLONGTERMED L) L)
CAML A,.HASEND
JRST .+2
CPOPJ: POPJ P,
CAILE A,377777
JRST CPOPJ
HLRE B,(A) ;((ATOM L) L)
AOJE B,CPOPJ
; (T (HASHCONS (LTCONS (CAR L))(LTCONS (CDR L)))
SKIPN B,(A)
JRST NNRET ; (NIL) -- SPECIAL RETURN
HRL ORIGPT,A ;SAVE PTR AND CONSED VALUE
PUSH P,ORIGPT
PUSH P,B
HLRZ A,(A) ;CAR IS LONG TERM
PUSHJ P,LCONS1
HRLZS A ;SAVE HERE
EXCH A,(P) ;CDR ORIG
PUSHJ P,LCONS1
HRRM A,(P)
POP P,CONSED ;CONSED IS LT-CONSED
POP P,ORIGPT ;LH IS ORIG PTR TO ORIG CONSED
SKIPE .FULL ;IF FULL NOW, CONS RESULTS
JRST FULL
HLRZ B,CONSED
; INITIAL HASH -- CAR XOR CDR
; A IS CDR LONGED, B IS CAR LONGED, CONSED IS NEW CONS WORD
XOR A,B
IDIV A,HASLEN
EXCH A,B
ADD A,.HASBAS
; A IS TABLE BASE + RESIDUE -- NEED TO KEEP QUOTIENT B FOR INCREMENT
; CHECK IF FIRST HASH HIT RIGHT NUMBER OR A FREE ENTRY
SKIPN (A) ;IS THERE SOMETHING IN THIS CELL?
MOVEM CONSED,(A) ;NO, NEW CONS -- THIS IS IT
CAMN CONSED,(A) ;IS IT THIS ONE?
POPJ P, ; YES, INDEED, DONE IN ONE
; PREPARE FOR INCREMENT LOOP
HRR ORIGPT,A ;TO DETECT TABLE FULL, LH IS ORIG PTR
IDIV B,HASLEN ;QUOTIENT MOD LENGTH IS INCREMENT FN.
JUMPN C,.+2
MOVEI C,1
MOVEI D,-1(HASLEN) ;COUNT INSTANCES
; EACH SUBSEQUENT PROBE LOCATION IS (PREVIOUS + QUOTIENT) MOD HASLEN -- THIS
; WILL COVER THE WHOLE TABLE BECAUSE HASLEN IS PRIME.
LK1: ADD A,C
CAML A,.HASEND
SUBI A,(HASLEN)
SKIPN (A)
MOVEM CONSED,(A)
CAMN CONSED,(A)
POPJ P,
SOJG D,LK1
FULL: SETOM .FULL
HLRZ A,ORIGPT
CAMN CONSED,(A) ;BOTH SIDES FULL?
POPJ P, ;YES
HLRZ A,CONSED
HRRZ B,CONSED
JRST CONS
NNRET: MOVEI A,NIL.NIL ;NIL.NIL IS 0, OR (NIL)
POPJ P,
; (UNLTCONS <ltcons'ed list>)
UNLTCONS:PUSHJ P,UNLT
MOVE B,.HASBAS
SUB B,.HASEND
HRLZS B
HRR B,.HASBAS
CLNUP: SKIPGE (B)
SETZM (B)
AOBJN B,CLNUP
HRRZS A
POPJ P,
UNLT: HRRZS A
JUMPE A,CPOPJ
CAILE A,377777
POPJ P,
HLRE B,(A)
AOJE B,CPOPJ ;ATOM
AOJE B,[HRRZ A,(A) ;ALREADY HANDLED CONS
JRST CPOPJ]
PUSH P,(A) ;CONS PAIR
MOVEI B, ;MAKE (CONS NIL <HASH TABLE CONS ADR>)
PUSHJ P,XCONS
HRLI A,-2
MOVEM A,@(A) ;NEW RESULT IN OLD WORD, LH MARKS DONE
PUSH P,A ;FINAL RESULT
HLRZ A,-1(P)
PUSHJ P,UNLT ;UNLTCONS THE CAR
EXCH A,-1(P) ;SAVE THE RESULT, AND
PUSHJ P,UNLT ; UNLTCONS THE CDR
POP P,B ;FINAL RESULT
POP P,C ;CAR RESULT
HRL A,C ;(CONS (CAR RESULT) (CDR RESULT))
MOVEM A,(B) ;PUT CONS INTO RESULT
HRRZ A,B
POPJ P,
; (LTOCCUPANCY) (LTAVERAGELOOKUP)(LTMAXLOOKUP)
; Ltoccupancy returns number of words filled. User must already
; know table size;
; Ltlookupaverage returns the average # of table probes needed to
; do an LTCONS, at the present time.
; Ltmaxlookup returns the length of the longerst chain.
LTOCCUPANCY↑:
MOVN B,.HASLEN
HRLS B
HRR B,.HASBAS
MOVEI A,
LTOLP: SKIPE (B)
ADDI A,1
AOBJN B,LTOLP
JRST FIX1A↑
LTAVERAGELOOKUP↑:
PUSH P,[0] ;-MAX CHAIN (-3)
PUSH P,[0] ;-SUM OF CHAINS (-2)
PUSH P,[0] ;-COUNT OF ENTRIES (-1)
PUSH P,.HASBAS ;→FIRST ENTRY (0)
AVLP: AOS B,(P)
CAMLE B,.HASEND ;DONE?
JRST AVDN ;YES
SKIPN C,-1(B) ;THIS ENTRY OCCUPIED?
JRST NOENT ;NO
SOS -1(P) ;COUNT ENTRIES
PUSH P,C ;CREATE CONS WORD OUTSIDE HASH SPACE
MOVEI A,(P)
PUSHJ P,LTCONS ;D IS HASLEN+1 - #PROBES
SUB P,[1,,1]
SUBI D,1(HASLEN) ;-#PROBES
ADDM D,-2(P)
CAMGE D,-3(P)
MOVEM D,-3(P) ;MAX # PROBES
NOENT: AOS (P)
JRST AVLP
AVDN: SUB P,[1,,1]
POP P,B
POP P,A
IDIV A,B
PUSHJ P,FIX1A↑ ;RESULT
POP P,B ;-MAX CHAIN
POPJ P, ;DONE
LTMAXLOOKUP↑:
PUSHJ P,LTAVERAGELOOKUP
MOVN A,B
JRST FIX1A ;MAX
.HASLEN:0 ;LENGTH OF HASH TABLE (ARRAY)
.FULL: 0 ;ON AFTER ANY LCONS FAILS, NO MORE LCONSES
.HASBAS:0 ;COPIES BASE PTR OF LCONS ARRAY
.HASEND:0 ;ONE PAST END OF ARRAY
BPRGSV: 0
BPRSV1: 0
BPNDSV: 0
FLAGSV: 0
NIL.NIL:0 ;SPECIAL VALUE FOR (NIL) -- TO AVOID HASH CONFUSION
END